using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Data;
using System.Data.SqlClient;

namespace Acms.SqlDal
{
    public class PostDal : Base
    {
        public PostDal() : base() { }

        public enum Fields
        {
            Id,
            SiteId,
            PostGuid,
            SiteName,
            ParentGuid,
            ParentPath,
            Name,
            DisplayName,
            TemplateId,
            TemplateName,
            NodeType,
            ThumbnailId,
            Summary,
            Sequence,
            CreatedDateTime,
            PublishFrom,
            PublishTo,
            RequiresPublishing,
            ReadyToPublish,
            Notes,
            SiteVersion,
            DeveloperLocked,
            TitleSummary,
            MetaKeywords
        }

        protected override void ReadRecord(Hashtable table, SqlDataReader reader)
        {
            GetReaderValue<int>(Fields.Id, reader, table);
            GetReaderValue<int>(Fields.SiteId, reader, table);
            GetReaderValue<Guid>(Fields.PostGuid, reader, table);
            GetReaderValue<string>(Fields.SiteName, reader, table);
            GetReaderValue<Guid?>(Fields.ParentGuid, reader, table);
            GetReaderValue<string>(Fields.ParentPath, reader, table);
            GetReaderValue<string>(Fields.Name, reader, table);
            GetReaderValue<string>(Fields.DisplayName, reader, table);
            GetReaderValue<int>(Fields.TemplateId, reader, table);
            GetReaderValue<string>(Fields.TemplateName, reader, table);
            GetReaderValue<int>(Fields.NodeType, reader, table);
            GetReaderValue<int?>(Fields.ThumbnailId, reader, table);
            GetReaderValue<string>(Fields.Summary, reader, table);
            GetReaderValue<int>(Fields.Sequence, reader, table);
            GetReaderValue<DateTime>(Fields.CreatedDateTime, reader, table);
            GetReaderValue<DateTime?>(Fields.PublishFrom, reader, table);
            GetReaderValue<DateTime?>(Fields.PublishTo, reader, table);
            GetReaderValue<bool>(Fields.RequiresPublishing, reader, table);
            GetReaderValue<bool>(Fields.ReadyToPublish, reader, table);
            GetReaderValue<string>(Fields.Notes, reader, table);
            GetReaderValue<DateTime?>(Fields.SiteVersion, reader, table);
            GetReaderValue<bool>(Fields.DeveloperLocked, reader, table);
            GetReaderValue<string>(Fields.TitleSummary, reader, table);
            GetReaderValue<string>(Fields.MetaKeywords, reader, table);
        }

        public Hashtable GetTopLevelBySiteId(int siteId, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetTopLevelBySiteId");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetItem(cmd);
        }

        public Hashtable[] GetAllBySiteId(int siteId, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetAllBySiteId");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetCollection(cmd);
        }


        public Hashtable[] GetAllBySiteIdMenuIdAndParentPath(int siteId, int menuId, string parentPath, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetAllBySiteIdMenuIdAndParentPath");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "MenuId", menuId, SqlDbType.Int);
            AddInputParameter(cmd, "ParentPath", parentPath, SqlDbType.VarChar, 255);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetCollection(cmd);
        }

        public Hashtable[] GetAllBySiteIdAndParentPath(int siteId, string parentPath, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetAllBySiteIdAndParentPath");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "ParentPath", parentPath, SqlDbType.VarChar, 255);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetCollection(cmd);
        }

        public Hashtable[] GetAllByMenuIdAndParentGuid(int siteId, int menuId, Guid parentGuid, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetAllByMenuIdAndParentGuid");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "MenuId", menuId, SqlDbType.Int);
            AddInputParameter(cmd, "ParentGuid", parentGuid, SqlDbType.UniqueIdentifier);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetCollection(cmd);
        }

        public Hashtable[] GetAllByMenuId(int siteId, int menuId, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetAllByMenuId");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "MenuId", menuId, SqlDbType.Int);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetCollection(cmd);
        }

        public Hashtable[] GetAllByParentGuid(int siteId, Guid parentGuid, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetAllByParentGuid");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "ParentGuid", parentGuid, SqlDbType.UniqueIdentifier);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetCollection(cmd);
        }


        public Hashtable GetBySiteUrlAndPath(string siteUrl, string path, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetBySiteUrlAndPath");
            AddInputParameter(cmd, "SiteUrl", siteUrl, SqlDbType.VarChar, 50);
            AddInputParameter(cmd, "Path", path, SqlDbType.VarChar, 255);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetItem(cmd);
        }

        public Hashtable GetBySiteIdAndPath(int siteId, string path, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetBySiteIdAndPath");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "Path", path, SqlDbType.VarChar, 255);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetItem(cmd);
        }

        public Hashtable GetById(int siteId, int id, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetById");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "Id", id, SqlDbType.Int);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetItem(cmd);
        }

        public Hashtable GetById(int id)
        {
            SqlCommand cmd = CreateCommand("GetByIdOnly");
            AddInputParameter(cmd, "Id", id, SqlDbType.Int);
            return ExecuteGetItem(cmd);
        }

        public Hashtable GetByPostGuid(int siteId, Guid postGuid, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetByPostGuid");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "PostGuid", postGuid, SqlDbType.UniqueIdentifier);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetItem(cmd);
        }

        public Hashtable[] GetCurrentVersions(int siteId, Guid postGuid)
        {
            SqlCommand cmd = CreateCommand("GetCurrentVersions");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "PostGuid", postGuid, SqlDbType.UniqueIdentifier);
            return ExecuteGetCollection(cmd);
        }

        public Hashtable[] GetCurrentVersionsByPostId(int siteId, int postId)
        {
            SqlCommand cmd = CreateCommand("GetCurrentVersionsByPostId");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "PostId", postId, SqlDbType.Int);
            return ExecuteGetCollection(cmd);
        }

        public void Update(ref int id, int siteId, ref string siteName, Guid postGuid, Guid? parentGuid, ref string parentPath, string name, string displayName, int templateId, ref string templateName, ref int nodeType, int? thumbnailId, string summary, ref int sequence, DateTime createdDateTime, DateTime? publishFrom, DateTime? publishTo, bool requiresPublishing, bool readyToPublish, string notes, bool developerLocked, string titleSummary, string metaKeywords, ref object concurencyId)
        {
            SqlCommand cmd = CreateCommand("Put");
            AddInputParameter(cmd, "Id", id, SqlDbType.Int);
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "PostGuid", postGuid, SqlDbType.UniqueIdentifier);
            AddInputParameter(cmd, "ParentGuid", parentGuid, SqlDbType.UniqueIdentifier);
            AddInputParameter(cmd, "Name", name, SqlDbType.VarChar, 100);
            AddInputParameter(cmd, "DisplayName", displayName, SqlDbType.VarChar, 100);
            AddInputParameter(cmd, "TemplateId", templateId, SqlDbType.Int);
            AddInputParameter(cmd, "ThumbnailId", thumbnailId, SqlDbType.Int);
            AddInputParameter(cmd, "Summary", summary, SqlDbType.VarChar, 2000);
            AddInputParameter(cmd, "Sequence", sequence, SqlDbType.Int);
            AddInputParameter(cmd, "PublishFrom", publishFrom, SqlDbType.DateTime);
            AddInputParameter(cmd, "PublishTo", publishTo, SqlDbType.DateTime);
            AddInputParameter(cmd, "Notes", notes, SqlDbType.NVarChar, 2000);
            AddInputParameter(cmd, "RequiresPublishing", requiresPublishing, SqlDbType.Bit);
            AddInputParameter(cmd, "ReadyToPublish", readyToPublish, SqlDbType.Bit);
            AddInputParameter(cmd, "CreatedDateTime", createdDateTime, SqlDbType.DateTime);
            AddInputParameter(cmd, "DeveloperLocked", developerLocked, SqlDbType.Bit);
            AddInputParameter(cmd, "TitleSummary", titleSummary, SqlDbType.VarChar, 500);
            AddInputParameter(cmd, "MetaKeywords", metaKeywords, SqlDbType.VarChar, 2000);
            AddInputParameter(cmd, "ConcurencyId", concurencyId, SqlDbType.Timestamp);
            AddOutputParameter(cmd, "IdOut", SqlDbType.Int);
            AddOutputParameter(cmd, "SiteNameOut", SqlDbType.VarChar, 50);
            AddOutputParameter(cmd, "ParentPathOut", SqlDbType.VarChar, 255);
            AddOutputParameter(cmd, "TemplateNameOut", SqlDbType.VarChar, 255);
            AddOutputParameter(cmd, "NodeTypeOut", SqlDbType.Int);
            AddOutputParameter(cmd, "SequenceOut", SqlDbType.Int);
            AddOutputParameter(cmd, "ConcurencyIdOut", SqlDbType.Timestamp);

            ExecuteCommand(cmd);

            id = GetOutputValue<int>(cmd, "IdOut");
            siteName = GetOutputValue<string>(cmd, "SiteNameOut");
            parentPath = GetOutputValue<string>(cmd, "ParentPathOut");
            templateName = GetOutputValue<string>(cmd, "TemplateNameOut");
            nodeType = GetOutputValue<int>(cmd, "NodeTypeOut");
            sequence = GetOutputValue<int>(cmd, "SequenceOut");
            concurencyId = GetOutputValue<byte[]>(cmd, "ConcurencyIdOut");

        }

        public void Delete(int id, object versionId)
        {
            SqlCommand cmd = CreateCommand("Delete");
            AddInputParameter(cmd, "Id", id, SqlDbType.Int);
            AddInputParameter(cmd, "VersionId", versionId, SqlDbType.Timestamp);
            ExecuteCommand(cmd);
        }

        public Hashtable[] GetAllByParentGuidAndTopicId(int siteId, Guid parentGuid, int topicId, DateTime? siteVersion, bool includeChildren, int startIndex, int pageSize, ref int totalRecords)
        {
            SqlCommand cmd = CreateCommand("GetAllByParentGuidAndTopicId");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "ParentGuid", parentGuid, SqlDbType.UniqueIdentifier);
            AddInputParameter(cmd, "TopicId", topicId, SqlDbType.Int);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            AddInputParameter(cmd, "IncludeChildren", includeChildren, SqlDbType.Bit);
            return ExecuteGetPagedCollection(cmd, startIndex, pageSize, ref totalRecords);
        }

        public Hashtable[] GetAllByTopicId(int siteId, int topicId, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetAllByTopicId");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "TopicId", topicId, SqlDbType.Int);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetCollection(cmd);
        }


        public Hashtable[] GetAllByTopicIdAndParentPath(int siteId, int topicId, string parentPath, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetAllByTopicIdAndParentPath");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "TopicId", topicId, SqlDbType.Int);
            AddInputParameter(cmd, "ParentPath", parentPath, SqlDbType.VarChar, 255);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetCollection(cmd);
        }

        public Hashtable[] GetAllByTopicIdsAndParentPath(int siteId, int[] topicIds, string parentPath, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetAllByTopicIdsAndParentPath");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "TopicIds", topicIds, SqlDbType.VarChar, 1000);
            AddInputParameter(cmd, "ParentPath", parentPath, SqlDbType.VarChar, 255);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetCollection(cmd);
        }

        public Hashtable[] GetAllByTopicGroupIdAndParentPath(int siteId, int topicGroupId, string parentPath, DateTime? siteVersion)
        {
            SqlCommand cmd = CreateCommand("GetAllByTopicGroupIdAndParentPath");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            AddInputParameter(cmd, "TopicGroupId", topicGroupId, SqlDbType.Int);
            AddInputParameter(cmd, "ParentPath", parentPath, SqlDbType.VarChar, 255);
            AddInputParameter(cmd, "SiteVersion", siteVersion, SqlDbType.DateTime);
            return ExecuteGetCollection(cmd);
        }

        public Hashtable[] GetAllWhereRequiresPublishing(int siteId)
        {
            SqlCommand cmd = CreateCommand("GetAllWhereRequiresPublishing");
            AddInputParameter(cmd, "SiteId", siteId, SqlDbType.Int);
            return ExecuteGetCollection(cmd);
        }

        public Hashtable[] GetAllByPostGuid(Guid postGuid)
        {
            SqlCommand cmd = CreateCommand("GetAllByPostGuid");
            AddInputParameter(cmd, "PostGuid", postGuid, SqlDbType.UniqueIdentifier);
            return ExecuteGetCollection(cmd);
        }


        public void SetPosition(int id, int siteID, Guid newParentGuid, ref int sequence, ref object concurencyId)
        {
            SqlCommand cmd = CreateCommand("SetPosition");
            AddInputParameter(cmd, "Id", id, SqlDbType.Int);
            AddInputParameter(cmd, "SiteId", siteID, SqlDbType.Int);
            AddInputParameter(cmd, "ParentGuid", newParentGuid, SqlDbType.UniqueIdentifier);
            AddInputParameter(cmd, "Sequence", sequence, SqlDbType.Int);
            AddInputParameter(cmd, "ConcurencyId", concurencyId, SqlDbType.Timestamp);
            AddOutputParameter(cmd, "SequenceOut", SqlDbType.Int);
            AddOutputParameter(cmd, "ConcurencyIdOut", SqlDbType.Timestamp);
            ExecuteCommand(cmd);

            sequence = GetOutputValue<int>(cmd, "SequenceOut");
            concurencyId = GetOutputValue<byte[]>(cmd, "ConcurencyIdOut");
        }

        public Hashtable Publish(int id, bool includeChidren, bool includeOnlyMarked, DateTime from, DateTime? to)
        {
            SqlCommand cmd = CreateCommand("Publish");
            AddInputParameter(cmd, "Id", id, SqlDbType.Int);
            AddInputParameter(cmd, "IncludeChidren", includeChidren, SqlDbType.Bit);
            AddInputParameter(cmd, "IncludeOnlyMarked", includeOnlyMarked, SqlDbType.Bit);
            AddInputParameter(cmd, "PublishFrom", from, SqlDbType.DateTime);
            AddInputParameter(cmd, "PublishTo", to, SqlDbType.DateTime);
            return ExecuteGetItem(cmd);
        }

    }
}
